<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Java 基础语法 02：面向对象编程</title>
    <link href="https://fonts.googleapis.com/css2?family=Merriweather:wght@400;700&family=Inter:wght@300;400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css">
    <style>
        :root {
            --primary-bg: #ffffff;
            --secondary-bg: #f8f9fa;
            --text-primary: #1a1a1a;
            --text-secondary: #4a5568;
            --accent-blue: #3b82f6;
            --border-light: #e2e8f0;
            --code-bg: #f7fafc;
            --shadow-subtle: 0 1px 3px rgba(0, 0, 0, 0.1);
            --shadow-card: 0 4px 6px rgba(0, 0, 0, 0.05);
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
            line-height: 1.7;
            color: var(--text-primary);
            background: var(--primary-bg);
            background-image: 
                linear-gradient(rgba(59, 130, 246, 0.02) 1px, transparent 1px),
                linear-gradient(90deg, rgba(59, 130, 246, 0.02) 1px, transparent 1px);
            background-size: 20px 20px;
            font-size: 16px;
            font-weight: 400;
        }

        .container {
            max-width: 1000px;
            margin: 0 auto;
            padding: 60px 40px;
        }

        /* Header */
        .header {
            text-align: center;
            margin-bottom: 80px;
            padding: 60px 0;
            background: linear-gradient(135deg, var(--secondary-bg) 0%, var(--primary-bg) 100%);
            border-radius: 16px;
            border: 1px solid var(--border-light);
        }

        .header h1 {
            font-family: 'Merriweather', serif;
            font-size: 3.5rem;
            font-weight: 700;
            color: var(--text-primary);
            margin-bottom: 20px;
            letter-spacing: -0.02em;
        }

        .header .subtitle {
            font-size: 1.25rem;
            color: var(--text-secondary);
            font-weight: 400;
        }

        /* Typography */
        h2 {
            font-family: 'Merriweather', serif;
            font-size: 2.25rem;
            font-weight: 700;
            color: var(--text-primary);
            margin: 60px 0 30px 0;
            line-height: 1.3;
            border-bottom: 3px solid var(--accent-blue);
            padding-bottom: 15px;
        }

        h3 {
            font-family: 'Merriweather', serif;
            font-size: 1.75rem;
            font-weight: 600;
            color: var(--text-primary);
            margin: 45px 0 25px 0;
            line-height: 1.4;
        }

        h4 {
            font-size: 1.25rem;
            font-weight: 600;
            color: var(--text-primary);
            margin: 35px 0 20px 0;
        }

        p {
            margin-bottom: 20px;
            color: var(--text-primary);
            line-height: 1.8;
        }

        /* Lists */
        ul, ol {
            margin: 20px 0;
            padding-left: 30px;
        }

        li {
            margin-bottom: 12px;
            line-height: 1.7;
            color: var(--text-primary);
        }

        li ul, li ol {
            margin: 10px 0;
        }

        /* Code blocks */
        pre {
            background: var(--code-bg);
            border: 1px solid var(--border-light);
            border-radius: 12px;
            padding: 25px;
            margin: 25px 0;
            overflow-x: auto;
            font-family: 'IBM Plex Mono', 'Consolas', monospace;
            font-size: 14px;
            line-height: 1.6;
            box-shadow: var(--shadow-subtle);
        }

        code {
            font-family: 'IBM Plex Mono', 'Consolas', monospace;
            font-size: 0.9em;
            background: var(--code-bg);
            padding: 3px 6px;
            border-radius: 4px;
            border: 1px solid var(--border-light);
        }

        pre code {
            background: none;
            padding: 0;
            border: none;
            border-radius: 0;
        }

        /* Emphasis */
        strong {
            font-weight: 600;
            color: var(--text-primary);
        }

        em {
            font-style: italic;
            color: var(--text-secondary);
        }

        /* Cards for sections */
        .section-card {
            background: var(--primary-bg);
            border: 1px solid var(--border-light);
            border-radius: 12px;
            padding: 40px;
            margin: 40px 0;
            box-shadow: var(--shadow-card);
            transition: all 0.3s ease;
        }

        .section-card:hover {
            box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
            transform: translateY(-2px);
        }

        /* Special styling for important notes */
        .note {
            background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
            border-left: 4px solid var(--accent-blue);
            padding: 20px 25px;
            margin: 25px 0;
            border-radius: 0 8px 8px 0;
            font-weight: 500;
        }

        .note strong {
            color: var(--accent-blue);
        }

        /* Responsive design */
        @media (max-width: 768px) {
            .container {
                padding: 30px 20px;
            }

            .header h1 {
                font-size: 2.5rem;
            }

            .header .subtitle {
                font-size: 1.1rem;
            }

            h2 {
                font-size: 1.875rem;
            }

            h3 {
                font-size: 1.5rem;
            }

            .section-card {
                padding: 25px;
            }

            pre {
                padding: 20px;
                font-size: 13px;
            }
        }

        /* Smooth scrolling */
        html {
            scroll-behavior: smooth;
        }

        /* Selection styling */
        ::selection {
            background: rgba(59, 130, 246, 0.2);
            color: var(--text-primary);
        }

        /* Focus styles for accessibility */
        *:focus {
            outline: 2px solid var(--accent-blue);
            outline-offset: 2px;
        }
    </style>
</head>
<body>
    <div class="container">
        <header class="header">
            <h1>Java 基础语法 02</h1>
            <p class="subtitle">面向对象编程：方法、类与对象、继承与多态</p>
        </header>

        <main>
            <section class="section-card">
                <h2>1. 方法 (Methods)</h2>
                <p>方法是一段可重用的代码块，用于执行特定的任务。方法可以使代码更加模块化、易于理解和维护。</p>

                <h3>1.1 方法定义</h3>
                <p>Java 中定义方法的语法如下：</p>
                <pre><code class="language-java">修饰符 返回值类型 方法名(参数列表) {
    // 方法体
    return 返回值; // 如果返回值类型不是void
}</code></pre>

                <ul>
                    <li><strong>修饰符 (Modifiers)</strong>：可选，用于定义方法的访问级别和行为。常见的修饰符包括：
                        <ul>
                            <li><code>public</code>: 公共访问修饰符，表示该方法可以被任何其他类访问。</li>
                            <li><code>private</code>: 私有访问修饰符，表示该方法只能在其定义的类内部访问。</li>
                            <li><code>protected</code>: 受保护访问修饰符，表示该方法可以被同一包内的类以及不同包中的子类访问。</li>
                            <li><code>static</code>: 静态修饰符，表示该方法属于类本身，而不是类的某个特定实例。静态方法可以直接通过类名调用，例如 <code>ClassName.methodName()</code>。</li>
                            <li><code>final</code>: 最终修饰符，表示该方法不能被子类重写（override）。</li>
                            <li><code>abstract</code>: 抽象修饰符，用于声明抽象方法。抽象方法没有方法体，必须在抽象类中声明，并由非抽象子类实现。</li>
                        </ul>
                        <em>示例：<code>public static int getCount()</code> 中 <code>public</code> 和 <code>static</code> 都是修饰符。</em>
                    </li>
                    <li><strong>返回值类型 (Return Type)</strong>：指定方法执行完毕后返回给调用者的数据的类型。它可以是任何有效的 Java 数据类型，包括：
                        <ul>
                            <li><strong>基本数据类型</strong>：如 <code>int</code>, <code>double</code>, <code>boolean</code>, <code>char</code> 等。</li>
                            <li><strong>引用数据类型</strong>：如 <code>String</code>, 数组，或自定义的类对象。</li>
                            <li><code>void</code>：如果方法不返回任何值，则使用 <code>void</code> 关键字。</li>
                        </ul>
                        <em>示例：<code>public String getName()</code> 返回一个字符串；<code>public void printMessage()</code> 不返回任何值。</em>
                    </li>
                    <li><strong>方法名 (Method Name)</strong>：方法的唯一标识符，用于调用方法。命名规则和约定：
                        <ul>
                            <li>遵循<strong>驼峰命名法</strong>（camelCase）：首字母小写，后续每个单词的首字母大写，例如 <code>getUserDetails</code>。</li>
                            <li>应具有描述性，清晰地表达方法的功能。</li>
                        </ul>
                    </li>
                    <li><strong>参数列表 (Parameter List)</strong>：定义方法在被调用时可以接收的输入数据。它位于方法名后的圆括号 <code>()</code> 内。
                        <ul>
                            <li><strong>格式</strong>：每个参数由 <code>数据类型 参数名</code> 组成，多个参数之间用逗号 <code>,</code> 分隔。</li>
                            <li><strong>可选性</strong>：方法可以没有参数，此时圆括号内为空，例如 <code>printHello()</code>。</li>
                            <li><strong>参数的作用域</strong>：参数的作用域仅限于方法体内部。</li>
                        </ul>
                    </li>
                    <li><strong>方法体 (Method Body)</strong>：包含在花括号 <code>{}</code> 中的一系列 Java 语句，定义了方法要执行的具体操作和逻辑。
                        <ul>
                            <li>方法体可以包含变量声明、控制流语句（如 <code>if</code>, <code>for</code>, <code>while</code>）、表达式、以及对其他方法的调用等。</li>
                            <li>如果方法定义有返回值，方法体中必须包含至少一个 <code>return</code> 语句来返回一个与声明的返回值类型兼容的值。</li>
                        </ul>
                    </li>
                    <li><strong><code>return</code> 返回值</strong>：<code>return</code> 语句用于从方法中返回一个值，并结束方法的执行。
                        <ul>
                            <li><strong>对于有返回值的方法</strong>：
                                <ul>
                                    <li>必须使用 <code>return expression;</code> 的形式，其中 <code>expression</code> 的计算结果必须与方法声明的返回值类型兼容（或可以自动转换为该类型）。</li>
                                    <li>方法体中可以有多个 <code>return</code> 语句（例如在不同的 <code>if-else</code> 分支中），但执行时只要遇到 return，则该方法执行结束。</li>
                                </ul>
                            </li>
                            <li><strong>对于 <code>void</code> 方法</strong> (不返回任何值)：<code>return;</code> 语句可以用来提前结束方法的执行，它是可选的。如果省略，方法会在执行完最后一条语句后自动结束。</li>
                        </ul>
                    </li>
                </ul>

                <p><strong>示例：</strong></p>
                <pre><code class="language-java">public class MethodExample {
    // 无参数，无返回值的方法
    public void printHello() {
        System.out.println("Hello, World!");
    }

    // 有参数，有返回值的方法
    public int add(int a, int b) {
        int sum = a + b;
        return sum;
    }

    public static void main(String[] args) {
        MethodExample obj = new MethodExample();
        obj.printHello(); // 调用无参数方法

        int result = obj.add(5, 3); // 调用有参数方法
        System.out.println("5 + 3 = " + result);
    }
}</code></pre>

                <h3>1.2 方法重载 (Method Overloading)</h3>
                <p>方法重载是指在同一个类中，可以有多个同名的方法，但它们的参数列表必须不同。参数列表的不同可以体现在：</p>
                <ul>
                    <li>参数个数不同</li>
                    <li>参数类型不同</li>
                    <li>参数顺序不同（如果类型也不同）</li>
                </ul>
                <div class="note">
                    <strong>注意：</strong> 方法重载与返回值类型和修饰符无关。
                </div>

                <p><strong>示例：</strong></p>
                <pre><code class="language-java">public class OverloadExample {
    public int calculate(int a, int b) {
        return a + b;
    }

    public double calculate(double a, double b) {
        return a + b;
    }

    public String calculate(String s1, String s2) {
        return s1 + s2;
    }

    public int calculate(int a, int b, int c) {
        return a + b + c;
    }

    public static void main(String[] args) {
        OverloadExample example = new OverloadExample();
        System.out.println("int sum: " + example.calculate(10, 20));
        System.out.println("double sum: " + example.calculate(10.5, 20.5));
        System.out.println("String concat: " + example.calculate("Hello", "World"));
        System.out.println("int sum (3 params): " + example.calculate(10, 20, 30));
    }
}</code></pre>

                <h4>方法重载的用处和适用场景：</h4>
                <p>方法重载主要有以下好处和应用场景：</p>
                <ol>
                    <li><strong>提高代码的可读性和易用性</strong>：
                        <ul>
                            <li>允许使用相同的名称来调用执行相似功能但参数不同的方法。这样可以使代码更直观，调用者不必记住多个相似功能但名称不同的方法。</li>
                            <li>例如，<code>System.out.println()</code> 方法就被重载了很多次，可以接受各种不同类型的参数（如 <code>int</code>, <code>double</code>, <code>String</code>, <code>Object</code> 等），方便开发者直接打印不同类型的数据而无需进行显式类型转换或调用不同的打印方法。</li>
                        </ul>
                    </li>
                    <li><strong>提供更灵活的接口</strong>：
                        <ul>
                            <li>可以为同一个操作提供多种参数组合方式，满足不同的调用需求。</li>
                            <li>例如，一个计算图形面积的方法，可以重载为接受不同参数（如计算圆形面积时传入半径，计算矩形面积时传入长和宽）。</li>
                        </ul>
                    </li>
                    <li><strong>简化构造器的使用</strong>：
                        <ul>
                            <li>在定义类的构造器时，经常使用重载来提供多种初始化对象的方式。可以有一个无参构造器提供默认初始化，同时有多个带不同参数的构造器，允许在创建对象时提供特定的初始值。</li>
                            <li>例如，一个 <code>Point</code> 类可以有 <code>Point()</code>（创建原点对象）、<code>Point(int x, int y)</code>（根据 x, y 坐标创建点对象）等构造器。</li>
                        </ul>
                    </li>
                    <li><strong>实现相似功能但处理不同数据类型</strong>：
                        <ul>
                            <li>当需要对不同数据类型执行逻辑上相似的操作时，可以使用方法重载。</li>
                            <li>例如，一个 <code>MathUtils</code> 类可能包含多个名为 <code>add</code> 的方法，分别用于整数相加、浮点数相加等：<code>add(int a, int b)</code> 和 <code>add(double a, double b)</code>。</li>
                        </ul>
                    </li>
                </ol>

                <h4>什么时候使用方法重载？</h4>
                <ul>
                    <li>当你希望用同一个方法名来表示一组在功能上相关或相似，但参数（数量、类型或顺序）不同的操作时。</li>
                    <li>当你需要为类的构造提供多种初始化选项时。</li>
                    <li>当你希望提供一个更简洁、更易于理解和使用的 API 时，避免为细微差异的功能创建大量不同的方法名。</li>
                </ul>
                <p>方法重载是一种强大的工具，它使得类能够提供更丰富、更灵活、更易于理解的接口。</p>

                <h3>1.3 方法作用域 (Method Scope)</h3>
                <p>在 Java 中，作用域（Scope）决定了变量和方法可以被访问的区域。理解作用域对于编写正确和可维护的代码至关重要。主要有以下几种作用域：</p>

                <ol>
                    <li><strong>类作用域 (Class Scope)</strong>：
                        <ul>
                            <li>成员变量（实例变量和静态变量）的作用域是整个类。它们可以在类的任何方法、构造器或块中被访问（遵循访问修饰符的规则）。</li>
                            <li>静态变量在类加载时创建，实例变量在对象创建时创建。</li>
                        </ul>
                    </li>
                    <li><strong>方法作用域 (Method Scope) / 局部作用域 (Local Scope)</strong>：
                        <ul>
                            <li><strong>局部变量 (Local Variables)</strong>：
                                <ul>
                                    <li>在方法内部声明的变量称为局部变量。它们的作用域从声明它们的位置开始，到包含它们的方法的末尾（即右花括号 <code>}</code>）。</li>
                                    <li>局部变量在方法被调用时创建，在方法执行完毕后销毁。</li>
                                    <li>它们不能在声明它们的方法之外被访问。</li>
                                    <li>不同的方法可以拥有同名的局部变量，它们之间不会产生冲突，因为它们属于不同的作用域。</li>
                                    <li>局部变量在使用前必须初始化。</li>
                                </ul>
                            </li>
                            <li><strong>方法参数 (Method Parameters)</strong>：
                                <ul>
                                    <li>方法参数的行为非常类似于局部变量。它们的作用域是整个方法体。</li>
                                    <li>参数在方法被调用时创建，并用传递给方法的值进行初始化。</li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                    <li><strong>块作用域 (Block Scope)</strong>：
                        <ul>
                            <li>块是由一对花括号 <code>{}</code> 定义的代码区域。例如 <code>if</code> 语句、<code>for</code> 循环、<code>while</code> 循环的循环体，或者甚至是一个独立的代码块。</li>
                            <li>在块内部声明的变量，其作用域从声明点开始，到该块的结束（即右花括号 <code>}</code>）。</li>
                            <li>块级变量在进入块时创建，在退出块时销毁。</li>
                            <li>块级变量不能在其定义的块外部被访问。</li>
                            <li><strong>嵌套作用域规则</strong>：
                                <ul>
                                    <li>内部块可以访问外部块中声明的变量。</li>
                                    <li>但是，内部块不能声明与外部块中已存在的局部变量同名的变量（这会导致编译错误，称为变量隐藏或遮蔽）。</li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                </ol>

                <p><strong>示例详细说明：</strong></p>
                <pre><code class="language-java">public class SimpleScopeExample {

    // 这是成员变量，也叫实例变量。它的作用域是整个类。
    // 也就是说，在 SimpleScopeExample 类的任何地方都可以使用它。
    String message = "Hello from instance variable!";

    // 这是主方法，程序的入口
    public static void main(String[] args) {
        // 创建一个 SimpleScopeExample 类的对象
        SimpleScopeExample example = new SimpleScopeExample();

        // 调用 printInstanceMessage 方法，这个方法可以访问成员变量 message
        example.printInstanceMessage();

        // 这是局部变量，它的作用域只在 main 方法内部。
        // 离开 main 方法后，这个变量就不能再使用了。
        int localNumber = 100;
        System.out.println("Main 方法中的局部变量 localNumber: " + localNumber);

        // 演示块级作用域
        if (true) {
            // 这个变量 blockVariable 的作用域只在这个 if 语句块内部。
            // 离开了这个 if 语句块，就不能再使用它了。
            String blockVar = "我只在 if 块里有效";
            System.out.println(blockVar);
        }
        // System.out.println(blockVariable); // 如果取消这行注释，会编译报错，因为 blockVariable 在这里不可见

        example.anotherMethod(200);
    }

    // 这是一个普通方法
    public void printInstanceMessage() {
        // 在这个方法里，我们可以直接访问成员变量 message
        System.out.println("printInstanceMessage 方法访问成员变量: " + message);
    }

    // 这是另一个方法，它有一个参数
    public void anotherMethod(int parameter) { // 'parameter' 是参数，它的作用域是整个 anotherMethod 方法
        // 这是局部变量，它的作用域只在 anotherMethod 方法内部。
        String localInMethod = "我在 anotherMethod 方法里";

        System.out.println("anotherMethod 的参数 parameter: " + parameter);
        System.out.println("anotherMethod 的局部变量 localInMethod: " + localInMethod);

        // 在这个方法里，我们也可以直接访问成员变量 message
        System.out.println("anotherMethod 方法访问成员变量: " + message);
    }
}</code></pre>

                <h3>1.4 参数传递 (Parameter Passing)</h3>
                <p>Java 中的参数传递只有一种方式：<strong>值传递 (pass by value)</strong>。</p>
                <ul>
                    <li><strong>基本数据类型参数</strong>：传递的是实际值的副本。在方法内部修改参数的值，不会影响到方法外部的原始变量。</li>
                    <li><strong>引用数据类型参数</strong>：传递的是对象引用的副本（即内存地址的副本）。方法内部可以通过这个副本引用访问和修改对象的属性，这些修改会影响到原始对象。但是，如果在方法内部将引用指向一个新的对象，原始对象的引用不会改变。</li>
                </ul>

                <p><strong>示例：</strong></p>
                <pre><code class="language-java">public class ParameterPassing {

    // 基本数据类型参数传递
    public void modifyNum(int num) {
        num = 100; // 修改的是num的副本
        System.out.println("在 modifyNum 方法内部, num = " + num);
    }

    // 引用数据类型参数传递
    public void modifyObject(MyNumber objNum) {
        objNum.setValue(200); // 修改的是objNum引用的对象的内容
        System.out.println("在 modifyObject 方法内部, objNum.value = " + objNum.getValue());

        objNum = new MyNumber(300); // objNum现在指向一个新的对象，不影响外部的引用
        System.out.println("在 modifyObject 方法内部 (新对象), objNum.value = " + objNum.getValue());
    }

    public static void main(String[] args) {
        ParameterPassing pp = new ParameterPassing();

        int originalNum = 10;
        System.out.println("调用 modifyNum 方法之前, originalNum = " + originalNum);
        pp.modifyNum(originalNum);
        System.out.println("调用 modifyNum 方法之后, originalNum = " + originalNum); // originalNum 仍然是 10

        System.out.println("---------------------");

        MyNumber originalObjNum = new MyNumber(20);
        System.out.println("调用 modifyObject 方法之前, originalObjNum.value = " + originalObjNum.getValue());
        pp.modifyObject(originalObjNum);
        System.out.println("调用 modifyObject 方法之后, originalObjNum.value = " + originalObjNum.getValue()); // originalObjNum.value 变为 200
    }
}

class MyNumber {
    private int value;

    public MyNumber(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}</code></pre>

                <h3>1.5 返回值 (Return Values)</h3>
                <p>方法可以返回一个值给调用者。返回值类型在方法定义时指定。如果方法不返回任何值，则返回值类型为 <code>void</code>。使用 <code>return</code> 语句来返回值。<code>return</code> 语句会立即终止方法的执行并将值返回。</p>

                <p><strong>示例：</strong></p>
                <pre><code class="language-java">public class ReturnValueExample {
    // 返回两个整数的和
    public int sum(int a, int b) {
        return a + b; // 返回计算结果
    }

    // 根据年龄判断是否成年，返回布尔值
    public boolean isAdult(int age) {
        if (age >= 18) {
            return true;
        }
        return false; // 或者直接 return age >= 18;
    }

    // 无返回值的方法
    public void greet(String name) {
        System.out.println("你好, " + name + "!");
        // return; // 可选，在void方法中，return用于提前结束方法
    }

    public static void main(String[] args) {
        ReturnValueExample rve = new ReturnValueExample();
        int total = rve.sum(10, 20);
        System.out.println("总和: " + total);

        boolean adult = rve.isAdult(25);
        System.out.println("是否成年 (25)? " + adult);

        rve.greet("小明");
    }
}</code></pre>

                <h3>1.6 <code>this</code> 关键字</h3>
                <p><code>this</code> 是一个关键字，它代表当前对象的引用。主要用途有：</p>
                <ol>
                    <li><strong>区分成员变量和局部变量/参数</strong>：当成员变量和局部变量或方法参数同名时，使用 <code>this.成员变量名</code> 来明确指代成员变量。</li>
                    <li><strong>在构造方法中调用其他构造方法</strong>：使用 <code>this(参数列表)</code> 来调用同一个类中的其他构造方法。这句调用必须是构造方法中的第一条语句。</li>
                    <li><strong>返回当前对象的引用</strong>：在某些方法中，可能需要返回当前对象本身，例如链式调用。</li>
                </ol>

                <p><strong>示例：</strong></p>
                <pre><code class="language-java">public class ThisExample {
    private String name;
    private int age;

    // 构造方法1: 使用this区分成员变量和参数
    public ThisExample(String name, int age) {
        this.name = name; // this.name 指的是成员变量name, name 指的是参数name
        this.age = age;
    }

    // 构造方法2: 调用构造方法1
    public ThisExample(String name) {
        this(name, 0); // 调用上面的构造方法，必须是第一句
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name; // 这里的this可以省略，因为没有歧义
    }

    public void display() {
        System.out.println("Name: " + this.name + ", Age: " + this.age);
    }

    // 返回当前对象引用，用于链式调用
    public ThisExample setAge(int age) {
        this.age = age;
        return this; // 返回当前对象
    }

    public static void main(String[] args) {
        ThisExample obj1 = new ThisExample("Alice", 30);
        obj1.display();

        ThisExample obj2 = new ThisExample("Bob");
        obj2.display();

        obj2.setAge(25).setName("Robert"); // 链式调用
        obj2.display();
    }
}</code></pre>
            </section>

            <section class="section-card">
                <h2>2. 类与对象 (Classes and Objects)</h2>
                <p>Java 是一种面向对象的编程语言。面向对象编程（OOP）的核心概念是类和对象。</p>
                <ul>
                    <li><strong>类 (Class)</strong>：是创建对象的蓝图或模板。它定义了一类对象的共同属性（成员变量）和行为（方法）。类是一种抽象的概念。</li>
                    <li><strong>对象 (Object)</strong>：是类的实例。对象是具体存在的实体，拥有类定义的属性和行为。</li>
                </ul>

                <h3>2.1 类与对象的概念</h3>
                <p><strong>声明一个类：</strong></p>
                <pre><code class="language-java">修饰符 class 类名 {
    // 成员变量 (属性)
    数据类型 变量名1;
    数据类型 变量名2;
    // ...

    // 构造方法 (用于创建对象)
    修饰符 类名(参数列表) {
        // 初始化代码
    }

    // 成员方法 (行为)
    修饰符 返回值类型 方法名(参数列表) {
        // 方法体
    }
}</code></pre>

                <p><strong>创建对象（实例化）：</strong></p>
                <p>使用 <code>new</code> 关键字来创建类的对象。</p>
                <pre><code class="language-java">类名 对象名 = new 类名(构造方法参数);</code></pre>

                <p><strong>访问对象的属性和方法：</strong></p>
                <p>使用点运算符 <code>.</code> 来访问对象的属性和调用对象的方法。</p>
                <pre><code class="language-java">对象名.属性名;
对象名.方法名(参数);</code></pre>

                <p><strong>示例：</strong></p>
                <pre><code class="language-java">// 定义一个汽车类 (Car Class)
class Car {
    // 属性
    String color;  // 颜色
    String model;  // 型号
    int year;      // 年份

    // 方法 (Methods)
    public void startEngine() {
        System.out.println(model + " 的引擎启动了！");
    }

    public void displayInfo() {
        System.out.println("汽车信息: " + year + "年 " + color + " " + model);
    }
}

// 主类，用于测试
public class CarExample {
    public static void main(String[] args) {
        // 创建汽车对象
        Car myCar = new Car();
        
        // 设置属性
        myCar.color = "红色";
        myCar.model = "丰田卡罗拉";
        myCar.year = 2023;
        
        // 调用方法
        myCar.displayInfo();
        myCar.startEngine();
        
        // 创建另一个汽车对象
        Car anotherCar = new Car();
        anotherCar.color = "蓝色";
        anotherCar.model = "本田雅阁";
        anotherCar.year = 2022;
        
        anotherCar.displayInfo();
        anotherCar.startEngine();
    }
}</code></pre>
            </section>

            <section class="section-card">
                <h2>3. 继承 (Inheritance)</h2>
                <p>继承是面向对象编程的核心特性之一。它允许一个类（子类）继承另一个类（父类）的属性和方法，从而实现代码的重用和扩展。</p>

                <h3>3.1 继承的基本概念</h3>
                <ul>
                    <li><strong>父类（超类、基类）</strong>：被继承的类</li>
                    <li><strong>子类（派生类）</strong>：继承父类的类</li>
                    <li><strong>继承关系</strong>：子类自动拥有父类的所有非私有属性和方法</li>
                </ul>

                <p><strong>继承语法：</strong></p>
                <pre><code class="language-java">class 子类名 extends 父类名 {
    // 子类特有的属性和方法
    // 可以重写父类的方法
}</code></pre>

                <p><strong>示例：</strong></p>
                <pre><code class="language-java">// 父类：动物
class Animal {
    protected String name;
    protected int age;
    
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void eat() {
        System.out.println(name + " 正在吃东西");
    }
    
    public void sleep() {
        System.out.println(name + " 正在睡觉");
    }
    
    public void displayInfo() {
        System.out.println("动物名称: " + name + ", 年龄: " + age);
    }
}

// 子类：狗
class Dog extends Animal {
    private String breed; // 品种
    
    public Dog(String name, int age, String breed) {
        super(name, age); // 调用父类构造方法
        this.breed = breed;
    }
    
    // 子类特有的方法
    public void bark() {
        System.out.println(name + " 正在汪汪叫");
    }
    
    // 重写父类方法
    @Override
    public void displayInfo() {
        super.displayInfo(); // 调用父类方法
        System.out.println("品种: " + breed);
    }
}

// 子类：猫
class Cat extends Animal {
    private boolean isIndoor; // 是否室内猫
    
    public Cat(String name, int age, boolean isIndoor) {
        super(name, age);
        this.isIndoor = isIndoor;
    }
    
    // 子类特有的方法
    public void meow() {
        System.out.println(name + " 正在喵喵叫");
    }
    
    // 重写父类方法
    @Override
    public void displayInfo() {
        super.displayInfo();
        System.out.println("是否室内猫: " + (isIndoor ? "是" : "否"));
    }
}

// 测试继承
public class InheritanceExample {
    public static void main(String[] args) {
        Dog myDog = new Dog("旺财", 3, "金毛");
        myDog.displayInfo();
        myDog.eat();    // 继承自父类
        myDog.sleep();  // 继承自父类
        myDog.bark();   // 子类特有方法
        
        System.out.println();
        
        Cat myCat = new Cat("咪咪", 2, true);
        myCat.displayInfo();
        myCat.eat();    // 继承自父类
        myCat.sleep();  // 继承自父类
        myCat.meow();   // 子类特有方法
    }
}</code></pre>

                <h3>3.2 <code>super</code> 关键字</h3>
                <p><code>super</code> 关键字用于访问父类的成员（属性和方法）。主要用途：</p>
                <ol>
                    <li><strong>调用父类构造方法</strong>：<code>super(参数列表)</code></li>
                    <li><strong>访问父类方法</strong>：<code>super.方法名()</code></li>
                    <li><strong>访问父类属性</strong>：<code>super.属性名</code></li>
                </ol>

                <div class="note">
                    <strong>重要：</strong> 在子类构造方法中，如果要调用父类构造方法，<code>super()</code> 必须是第一条语句。
                </div>

                <h3>3.3 方法重写 (Method Overriding)</h3>
                <p>方法重写是指子类重新定义父类中已有的方法。重写的方法必须与父类方法具有相同的方法名、参数列表和返回值类型。</p>

                <p><strong>重写规则：</strong></p>
                <ul>
                    <li>方法名、参数列表、返回值类型必须与父类方法完全相同</li>
                    <li>子类方法的访问修饰符不能比父类方法更严格</li>
                    <li>子类方法不能抛出比父类方法更多的异常</li>
                    <li>使用 <code>@Override</code> 注解（推荐）</li>
                </ul>

                <pre><code class="language-java">class Vehicle {
    public void start() {
        System.out.println("交通工具启动");
    }
    
    public void stop() {
        System.out.println("交通工具停止");
    }
}

class Motorcycle extends Vehicle {
    @Override
    public void start() {
        System.out.println("摩托车点火启动");
    }
    
    // 继承父类的 stop() 方法，不重写
}</code></pre>
            </section>

            <section class="section-card">
                <h2>4. 多态 (Polymorphism)</h2>
                <p>多态是面向对象编程的重要特性，它允许同一个接口表示不同的底层数据类型。在 Java 中，多态主要通过继承和方法重写来实现。</p>

                <h3>4.1 多态的概念</h3>
                <p>多态的核心思想是：<strong>一个引用变量可以指向不同类型的对象，并且在运行时根据实际对象类型调用相应的方法</strong>。</p>

                <p><strong>多态的实现条件：</strong></p>
                <ol>
                    <li>继承关系（子类继承父类）</li>
                    <li>方法重写（子类重写父类方法）</li>
                    <li>父类引用指向子类对象</li>
                </ol>

                <h3>4.2 多态的语法</h3>
                <pre><code class="language-java">父类类型 引用变量 = new 子类类型();</code></pre>

                <p><strong>示例：</strong></p>
                <pre><code class="language-java">// 抽象父类 Shape
abstract class Shape {
    protected String name;
    
    public Shape(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    
    // 抽象方法，子类必须实现
    public abstract double getArea();
    public abstract void draw();
}

// 子类 Circle 继承自 Shape
class Circle extends Shape {
    private double radius;
    
    public Circle(String name, double radius) {
        super(name);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public void draw() {
        System.out.println("正在绘制圆形 " + getName() + "，半径: " + radius);
    }
    
    // Circle 特有的方法
    public double getRadius() {
        return radius;
    }
}

// 子类 Rectangle 继承自 Shape
class Rectangle extends Shape {
    private double width;
    private double height;
    
    public Rectangle(String name, double width, double height) {
        super(name);
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
    
    @Override
    public void draw() {
        System.out.println("正在绘制矩形 " + getName() + "，宽度: " + width + ", 高度: " + height);
    }
    
    // Rectangle 特有的方法
    public double getWidth() {
        return width;
    }
    
    public double getHeight() {
        return height;
    }
}

// 主类，演示多态
public class PolymorphismWithShapes {
    public static void main(String[] args) {
        
        System.out.println("\n--- 使用数组处理不同类型的形状 (多态的应用场景) ---");
        Shape[] shapes = new Shape[3];
        shapes[0] = new Circle("红色圆形", 3.0);
        shapes[1] = new Rectangle("蓝色矩形", 2.0, 5.0);
        shapes[2] = new Circle("黄色小圆", 1.5); // 可以是不同参数的同一种形状
        
        for (Shape currentShape : shapes) {
            System.out.println("\n处理形状: " + currentShape.getName());
            currentShape.draw(); // 多态调用 draw()
            System.out.println("面积: " + currentShape.getArea()); // 多态调用 getArea()
        }
    }
}</code></pre>

                <h3>4.3 多态的优势</h3>
                <ul>
                    <li><strong>代码复用</strong>：可以用统一的方式处理不同类型的对象</li>
                    <li><strong>扩展性</strong>：添加新的子类时，不需要修改现有代码</li>
                    <li><strong>维护性</strong>：降低代码耦合度，提高代码的可维护性</li>
                    <li><strong>灵活性</strong>：在运行时决定调用哪个方法，增加程序的灵活性</li>
                </ul>

                <div class="note">
                    <strong>注意：</strong> 多态中，父类引用只能调用父类中定义的方法，不能直接调用子类特有的方法。如果需要调用子类特有方法，需要进行类型转换（向下转型）。
                </div>
            </section>
        </main>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
</body>
</html>